package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.HistoricActivity;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.CarPackageAuditMapper;
import com.ruoyi.business.service.ICarPackageAuditService;
import com.ruoyi.business.service.IDefinitionNodeService;
import com.ruoyi.business.service.IProcessService;
import com.ruoyi.business.service.IServiceItemService;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * 审核列Service业务层处理
 * 
 * @author wolfcode
 * @date 2021-07-20
 */
@Service
public class CarPackageAuditServiceImpl implements ICarPackageAuditService 
{
    @Autowired
    private CarPackageAuditMapper carPackageAuditMapper;
    @Autowired
    private IProcessService processService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IServiceItemService serviceItemService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;
    @Autowired
    private SysUserMapper sysUserMapper;
    /**
     * 查询审核列
     * @param id 审核列ID
     * @return 审核列
     */
    @Override
    public CarPackageAudit selectCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.selectCarPackageAuditById(id);
    }

    /**
     * 查询审核列列表
     * 
     * @param carPackageAudit 审核列
     * @return 审核列
     */
    @Override
    public List<CarPackageAudit> selectCarPackageAuditList(CarPackageAudit carPackageAudit)
    {
        List<CarPackageAudit> audits = carPackageAuditMapper.selectCarPackageAuditList(carPackageAudit);
        Task task = null;
        for (CarPackageAudit audit : audits) {
            task = processService.getTaskByProcessInstanceId(audit.getInstanceId());
            audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class));

            SysUser sysUser = sysUserService.selectUserById(Long.parseLong(audit.getCreateBy()));
            audit.setCreateByName(sysUser.getUserName());
            if (task != null) {
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
            }else {
                audit.setTaskName("已结束");
            }
        }
        return audits;
    }

    /**
     * 新增审核列
     * 
     * @param carPackageAudit 审核列
     * @return 结果
     */
    @Override
    public int insertCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        carPackageAudit.setCreateTime(DateUtils.getNowDate());
        return carPackageAuditMapper.insertCarPackageAudit(carPackageAudit);
    }

    /**
     * 修改审核列
     * 
     * @param carPackageAudit 审核列
     * @return 结果
     */
    @Override
    public int updateCarPackageAudit(CarPackageAudit carPackageAudit)
    {
        return carPackageAuditMapper.updateCarPackageAudit(carPackageAudit);
    }

    /**
     * 删除审核列对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditByIds(String ids)
    {
        return carPackageAuditMapper.deleteCarPackageAuditByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除审核列信息
     * 
     * @param id 审核列ID
     * @return 结果
     */
    @Override
    public int deleteCarPackageAuditById(Long id)
    {
        return carPackageAuditMapper.deleteCarPackageAuditById(id);
    }

    @Override
    @Transactional
    public void cancelApply(String instanceId, Long id) {

        // 1.把快照表的信息(状态修改成撤销,审核人设置为空)
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(id);
        audit.setAuditors("");
        audit.setStatus(CarPackageAudit.STATUS_CANCEL);
        carPackageAuditMapper.updateCarPackageAudit(audit);
        // 2.把服务项的状态修改成初始化
        ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(), ServiceItem.class);
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT); //状态修改为初始化
        serviceItemService.updateServiceItemNoCondition(serviceItem); //重写方法,之前的方法会判断状态,如果处于审核中是不允许修改的
        // 3.删除流程
        processService.deleteProcessInstanceByInstanceId(instanceId);
    }

    @Override
    public List<CarPackageAudit> findTodoList() {
        //1.查询当前登录用户关于汽车审核所有的待办任务总数
        long count = processService.selectTodoTaskCount(ShiroUtils.getUserId().toString(),CarPackageAudit.DEFINITION_KEY);

        if (count != 0){
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            //2.查询当前登录用户关于汽车审核所有的待办任务集合
            List<Task> taskList = processService.selectTodoTaskList(CarPackageAudit.DEFINITION_KEY,
                    ShiroUtils.getUserId().toString(),
                    (pageNum-1)*pageSize,
                    pageSize);
            //3.遍历待办任务,查询对应的CarPackAgeAudit
            List<CarPackageAudit> resultList = new ArrayList<>();
            CarPackageAudit audit;
            for (Task task : taskList) {
                ProcessInstance processInstance = processService
                        .getProcessInstanceById(task.getProcessInstanceId());
                String businessKey = processInstance.getBusinessKey();
                audit = carPackageAuditMapper.selectCarPackageAuditById(Long.parseLong(businessKey));
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
                audit.setCreateByName(sysUserService.selectUserById(Long.parseLong(audit.getCreateBy())).getUserName());
                resultList.add(audit);
            }
            //封装成Page对象返回
            Page<CarPackageAudit> list = new Page<>();
            list.setTotal(count);
            list.setPageNum(pageNum);
            list.setPageSize(pageSize);
            list.addAll(resultList);
            return list;
        }else {
            //如果总数为0,返回空集合回去
            return Collections.EMPTY_LIST;
        }
    }

    @Override
    @Transactional
    public void complete(String taskId, Boolean auditStatus, String comment) {

        // 任务处理
        Task task = processService.getTaskByTaskId(taskId);
        ProcessInstance processInstance = processService.getProcessInstanceById(task.getProcessInstanceId());
        String businessKey = processInstance.getBusinessKey();
        // 任务属于候选人任务,先领取
        // 给任务添加批注信息
        // 给任务添加流程变量,流程变量的名字当前任务的id 流程的值 auditStatus
        processService.claimAndComplete(task, ShiroUtils.getUserId().toString(),auditStatus,comment);
        // 判断流程是否已经结束了
        // 如果流程结束了,审核就通过
        // 如何判断流程已经结束?
        Task nextTask = processService.getTaskByProcessInstanceId(task.getProcessInstanceId());
        // 根据流程实例ID获取下一个节点. 下一个节点为空: 流程已经结束,审核通过, 下个不为空: 流程没有结束
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(Long.parseLong(businessKey));
        if (Objects.isNull(nextTask)) {
            audit.setStatus(CarPackageAudit.STATUS_PASS);   //审核通过
            audit.setAuditors("");
            ServiceItem item = JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class);
            item.setAuditStatus(ServiceItem.AUDITSTATUS_APPROVED);
            serviceItemService.updateServiceItemNoCondition(item);
        }else {
            // t_car_pack_audit 和 t_service_item修改审核状态
            // 下一个节点不为空:流程节点没有结束
            if (auditStatus){
                // 如果auditStatus为true
                //      根据下一个节点的Id在t_definition_node寻找该节点的审核人,给该节点设置候选人
                List<String> userNameList = new ArrayList<>();
                String taskDefinitionKey = nextTask.getTaskDefinitionKey();
                List<SysUser> auditors = definitionNodeService.queryByTaskDefinitionByKey(taskDefinitionKey);
                for (SysUser user : auditors) {
                    processService.addCandidateUser(nextTask,user.getUserId());
                    userNameList.add(user.getUserName());
                }
                audit.setAuditors(userNameList.toString());
            }else {
                // 如果auditStatus为false
                //      获取到该流程发起人,给当前节点设置对应的候选人为当前流程发起人
                processService.addCandidateUser(nextTask,Long.parseLong(audit.getCreateBy()));
            //      t_car_pack_audit的状态修改成审核拒绝 1
                audit.setAuditors(audit.getCreateByName());
                audit.setStatus(CarPackageAudit.STATUS_REJECT);
            }
        }
        carPackageAuditMapper.updateCarPackageAudit(audit);
    }

    @Override
    @Transactional
    public void updateCarPackageAuditServiceItemInfo(String carPackageAuditId,ServiceItem serviceItem) {
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(Long.parseLong(carPackageAuditId));
        audit.setServiceItemInfo(JSON.toJSONString(serviceItem));
        carPackageAuditMapper.updateCarPackageAudit(audit);
        serviceItemService.updateServiceItemNoCondition(serviceItem);
    }

    @Override
    @Transactional
    public void reApply(String taskId, Long carPackageAuditId) {
        // 添加批注,领取任务,完成任务
        Task task = processService.getTaskByTaskId(taskId);
        CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(carPackageAuditId);
        //2.重新设置流程变量
        ServiceItem serviceItem = JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class);
        processService.setVariable(taskId,"money",serviceItem.getDiscountPrice().longValue());
        processService.claimAndComplete(task,ShiroUtils.getUserId(),"重新申请");
        // 查询下一个节点,查询对应的候选人,给任务添加一个候选人
        Task nextTask = processService.getTaskByProcessInstanceId(task.getProcessInstanceId());
        String taskDefinitionKey = nextTask.getTaskDefinitionKey();
        List<SysUser> sysUsers = definitionNodeService.queryByTaskDefinitionByKey(taskDefinitionKey);
        List<String> auditors = new ArrayList<>();
        for (SysUser user : sysUsers) {
            processService.addCandidateUser(nextTask,user.getUserId());
            auditors.add(user.getUserName());
        }
        // 根据carPackageAuditId查询carPackageAudit对象,更新状态
        // 更新carPackageAudit对象的auditors字段
        audit.setStatus(CarPackageAudit.STATUS_IN_ROGRESS);
        audit.setAuditors(auditors.toString());
        carPackageAuditMapper.updateCarPackageAudit(audit);
    }

    @Override
    public List<CarPackageAudit> selectDoneList(CarPackageAudit carPackageAudit) {

        // 获取当前登录用户的id
        // HistoricTaskInstance  只是包含用户历史任务
        String userId = ShiroUtils.getUserId().toString();
        // 获取已办任务的总数
        long count = processService.getHistoricTaskCount(CarPackageAudit.DEFINITION_KEY,userId);
        if (count > 0) {
            // 获取前台传入的pageNum和pageSize
            PageDomain pageDomain = TableSupport.buildPageRequest();
            Integer pageNum = pageDomain.getPageNum();
            Integer pageSize = pageDomain.getPageSize();
            Integer starNum = (pageNum-1)*pageSize;
            List<HistoricTaskInstance> historicTaskInstances = processService.selectHistoricTaskList(
                    CarPackageAudit.DEFINITION_KEY,
                    userId,
                    starNum,
                    pageSize
            );
            List<CarPackageAudit> resultList = new ArrayList<>();
            for (HistoricTaskInstance task : historicTaskInstances) {
                // 如果任务已经完成,通过下面的方法是获取不到流程实例对象
               HistoricProcessInstance instance = processService.getHistoricProcessInstanceById(task.getProcessInstanceId());
                String businessKey = instance.getBusinessKey();
                CarPackageAudit audit = carPackageAuditMapper.selectCarPackageAuditById(Long.parseLong(businessKey));
                audit.setTaskName(task.getName());
                audit.setTaskId(task.getId());
                audit.setServiceItem(JSON.parseObject(audit.getServiceItemInfo(),ServiceItem.class));
                audit.setDoneTime(task.getEndTime());
                audit.setCreateByName(sysUserService.selectUserById(Long.valueOf(audit.getCreateBy())).getUserName());
                resultList.add(audit);

            }
            //封装成Page对象返回
            Page<CarPackageAudit> list = new Page<>();
            list.setTotal(count);
            list.setPageNum(pageNum);
            list.setPageSize(pageSize);
            list.addAll(resultList);
            return list;
        }else {
            return Collections.EMPTY_LIST;
        }
    }

    @Override
    public List<HistoricActivity> queryHistoricTaskInfo(Long instanceId) {

        //查询集合
        List<HistoricActivityInstance> instanceList = processService.selectHistoryTaskList(instanceId);
        List<HistoricActivity> resultList = new ArrayList<>();
        //遍历集合
        for (HistoricActivityInstance instance : instanceList) {
            HistoricActivity historicActivity = new HistoricActivity();
            // 拷贝属性
            BeanUtils.copyProperties(instance,historicActivity);
            // 查询审核批注
            historicActivity.setComment(processService.getTaskComment(instance.getTaskId()));
            String assignee = instance.getAssignee();
            if(Objects.nonNull(assignee)){
                SysUser sysUser = sysUserMapper.selectUserById(Long.parseLong(assignee));
                if (sysUser != null) {
                    //设置审核人姓名
                    historicActivity.setAssigneeName(sysUser.getUserName());
                }
            }
            resultList.add(historicActivity);
        }
        return resultList;
    }
}
